#include "jrpc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

cJSON* method_subtract1(void* data, const cJSON* request) {
    printf("Call method: %s\n", cJSON_GetObjectItem(request, "method")->valuestring);
    cJSON* id = cJSON_GetObjectItem(request, "id");
    if (!id) {
        return jrpc_create_error_response(JRPC_INVALID_REQUEST, "Invalid request", NULL);
    }

    cJSON* params = cJSON_GetObjectItem(request, "params");
    if (!params || !cJSON_IsArray(params)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* minuend = cJSON_GetArrayItem(params, 0);
    if (!minuend || !cJSON_IsNumber(minuend)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* subtrahend = cJSON_GetArrayItem(params, 1);
    if (!subtrahend || !cJSON_IsNumber(subtrahend)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* result = cJSON_CreateNumber(cJSON_GetNumberValue(minuend) - cJSON_GetNumberValue(subtrahend));
    return jrpc_create_response(result, NULL, id);
}

cJSON* method_subtract2(void* data, const cJSON* request) {
    printf("Call method: %s\n", cJSON_GetObjectItem(request, "method")->valuestring);
    cJSON* id = cJSON_GetObjectItem(request, "id");
    if (!id) {
        return jrpc_create_error_response(JRPC_INVALID_REQUEST, "Invalid request", NULL);
    }

    cJSON* params = cJSON_GetObjectItem(request, "params");
    if (!params || !cJSON_IsObject(params)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* minuend = cJSON_GetObjectItem(params, "minuend");
    if (!minuend || !cJSON_IsNumber(minuend)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* subtrahend = cJSON_GetObjectItem(params, "subtrahend");
    if (!subtrahend || !cJSON_IsNumber(subtrahend)) {
        return jrpc_create_error_response(JRPC_INVALID_PARAMS, "Invalid params", id);
    }

    cJSON* result = cJSON_CreateNumber(cJSON_GetNumberValue(minuend) - cJSON_GetNumberValue(subtrahend));
    return jrpc_create_response(result, NULL, id);
}

cJSON* method_update(void* data, const cJSON* request) {
    printf("Call method: %s\n", cJSON_GetObjectItem(request, "method")->valuestring);
    cJSON* params = cJSON_GetObjectItem(request, "params");
    if (params && cJSON_IsArray(params)) {
        for (int i = 0; i < cJSON_GetArraySize(params); i++) {
            printf("%f\n", cJSON_GetNumberValue(cJSON_GetArrayItem(params, i)));
        }
    }

    return NULL;
}

int main() {
    jrpc_register_method("subtract1", method_subtract1, NULL);
    jrpc_register_method("subtract2", method_subtract2, NULL);
    jrpc_register_method("update", method_update, NULL);
    
    // 模拟接收客户端请求
    char input_buffer[BUFSIZ];

    while (1) {
        if (!fgets(input_buffer, sizeof(input_buffer), stdin)) {
            break;
        }
        
        // 移除换行符
        input_buffer[strcspn(input_buffer, "\r\n")] = 0;

        // 解析请求
        cJSON* request = cJSON_Parse(input_buffer);
        if (!request) {
            fprintf(stderr, "Error: %s\n", cJSON_GetErrorPtr());
            //返回错误响应
            cJSON* error = cJSON_CreateObject();
            cJSON_AddNumberToObject(error, "code", JRPC_PARSE_ERROR);
            cJSON_AddStringToObject(error, "message", "Parse error");
            cJSON* response = jrpc_create_response(NULL, error, NULL);
            char* jsons = cJSON_PrintUnformatted(response);
            puts(jsons);
            continue;
        }

        if (cJSON_IsArray(request)) {
            //TODO: 支持BATCH请求
            cJSON_free(request);
            continue;
        }

        cJSON* response = jrpc_invoke_method(request);
        if (response) {
            char* jsons = cJSON_PrintUnformatted(response);
            puts(jsons);
            cJSON_free(response);
            free(jsons);
        }

        cJSON_free(request);
    }

    return 0;
}